package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.ObjectUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.dto.ReplyDTO;
import com.tianji.learning.dto.UserCount;
import com.tianji.learning.entity.InteractionQuestion;
import com.tianji.learning.entity.InteractionReply;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.query.ReplyPageQuery;
import com.tianji.learning.service.IInteractionQuestionService;
import com.tianji.learning.service.IInteractionReplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动问题的回答或评论 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-05-29
 */
@Service
public class InteractionReplyServiceImpl extends ServiceImpl<InteractionReplyMapper, InteractionReply> implements IInteractionReplyService {


    @Autowired
    private UserClient userClient;

    @Autowired
    private IInteractionQuestionService questionService;
    /**
     * 分页查询互动问题的回答或评论--管理端
     *
     * @param query
     * @return
     */
    @Override
    public PageDTO<ReplyDTO> queryQuestionAdminPage(ReplyPageQuery query) {
        //1.组装条件
        Long questionId = query.getQuestionId();
        Long answerId = query.getAnswerId();
        if(questionId == null & answerId == null){
            throw new BadRequestException("条件不能为空！");
        }
        Page<InteractionReply> page = this.lambdaQuery()
                .eq(questionId != null, InteractionReply::getQuestionId, questionId)
                .eq(questionId != null, InteractionReply::getTargetReplyId, 0)
                .eq(questionId != null, InteractionReply::getAnswerId, 0)
                .eq(answerId != null, InteractionReply::getAnswerId, answerId)
                .page(query.toMpPage("create_time", false));
        List<InteractionReply> records = page.getRecords();

        if(ObjectUtils.isEmpty(records)){
            return PageDTO.empty(page);
        }
        //3.获取用户信息
        Set<Long> ids = new HashSet<>();
        for (InteractionReply record : records) {
            if (!record.getHidden()) {
                ids.add(record.getUserId());
            }
            if (record.getTargetUserId() != null && record.getTargetUserId() != 0) {
                ids.add(record.getTargetUserId());
            }
        }
        //3.1 如果是问题，则需要下面每个回复的评论数
        Map<Long, Integer> numMap = new HashMap<>();
        if (questionId != null) {
            //select answer_id id ,COUNT(*) from interaction_reply group by answer_id
            numMap = this.baseMapper
                    .userCountLit(null).stream()
                    .collect(Collectors.toMap(UserCount::getId, UserCount::getNum));
        }
        List<UserDTO> users = userClient.queryUserByIds(ids);
        //集合转MAPu=
        Map<Long, UserDTO> uMap = users.stream().collect(Collectors.toMap(UserDTO::getId, u -> u));
        //4.组装vo实体

        List<ReplyDTO> voList = new ArrayList<>(records.size());
        for (InteractionReply record : records) {
            ReplyDTO vo = BeanUtils.copyBean(record, ReplyDTO.class);
            //评论用户是否匿名
            if (!record.getAnonymity()) {
                //获取用户
                UserDTO u = uMap.get(record.getUserId());
                vo.setUserName(u.getName());
                vo.setUserIcon(u.getIcon());
            }
            //被评论用户
            if (record.getTargetUserId() != null && record.getTargetUserId() != 0) {
                UserDTO u = uMap.get(record.getTargetUserId());
                vo.setTargetUserName(u.getName());
            }
            //问题回答数
            if (questionId != null) {
                Integer num = numMap.getOrDefault(record.getId(),0);
                vo.setAnswerTimes(num);
            }
            // TODO 获取点赞数
            voList.add(vo);
        }
        return PageDTO.of(page,voList);
    }

    @Override
    public PageDTO<ReplyDTO> queryQuestionPage(ReplyPageQuery query) {
        //1.组装条件
        Long questionId = query.getQuestionId();
        Long answerId = query.getAnswerId();
        if(questionId == null && answerId == null){
            throw new BadRequestException("条件不能为空！");
        }
        //2.分页查询
        Page<InteractionReply> page = this.lambdaQuery()
                .eq(questionId != null, InteractionReply::getQuestionId, questionId)
                .eq(questionId != null, InteractionReply::getTargetReplyId, 0)
                .eq(questionId != null, InteractionReply::getAnswerId, 0)
                .eq(answerId != null, InteractionReply::getAnswerId, answerId)
                .eq(InteractionReply::getHidden,false)
                .page(query.toMpPage("create_time", false));
        List<InteractionReply> records = page.getRecords();
        if(ObjectUtils.isEmpty(records)){
            return PageDTO.empty(page);
        }
        //3.获取用户信息
        Set<Long> ids = new HashSet<>();
        for (InteractionReply record : records) {
            if (!record.getHidden()) {
                ids.add(record.getUserId());
            }
            if (record.getTargetUserId() != null && record.getTargetUserId() != 0) {
                ids.add(record.getTargetUserId());
            }
        }
        //3.1 如果是问题，则需要下面每个回复的评论数
        Map<Long, Integer> numMap = new HashMap<>();
        if (questionId != null) {
            //select answer_id id ,COUNT(*) from interaction_reply group by answer_id
            numMap = this.baseMapper
                    .userCountLit(true).stream()
                    .collect(Collectors.toMap(UserCount::getId, UserCount::getNum));
        }
        List<UserDTO> users = userClient.queryUserByIds(ids);
        //集合转MAPu=
        Map<Long, UserDTO> uMap = users.stream().collect(Collectors.toMap(UserDTO::getId, u -> u));
        //4.组装vo实体

        List<ReplyDTO> voList = new ArrayList<>(records.size());
        for (InteractionReply record : records) {
            ReplyDTO vo = BeanUtils.copyBean(record, ReplyDTO.class);
            //评论用户是否匿名
            if (!record.getAnonymity()) {
                //获取用户
                UserDTO u = uMap.get(record.getUserId());
                vo.setUserName(u.getName());
                vo.setUserIcon(u.getIcon());
            }
            //被评论用户
            if (record.getTargetUserId() != null && record.getTargetUserId() != 0) {
                UserDTO u = uMap.get(record.getTargetUserId());
                vo.setTargetUserName(u.getName());
            }
            //问题回答数
            if (questionId != null) {
                Integer num = numMap.getOrDefault(record.getId(),0);
                vo.setReplyTimes(num);
            }
            // TODO 获取点赞数
            voList.add(vo);
        }
        return PageDTO.of(page,voList);
    }

    /**
     * 新增回答或评论
     *
     * @param dto
     */
    @Override
    public void savaReplies(ReplyDTO dto) {
        //1.条件判断
        Long userId = UserContext.getUser();
        Long questionId = dto.getQuestionId();
        Long answerId = dto.getAnswerId();
        String targetReplyId = dto.getTargetReplyId();
        //1.2 新增数据
        InteractionReply po = BeanUtils.copyBean(dto, InteractionReply.class);
        po.setUserId(userId);
        boolean result = this.save(po);
        if(!result){
            throw new BadRequestException("新增失败");
        }
        //2.是回答还是评论
        if (answerId == null && "".equals(targetReplyId)) {
            //2.1回答：修改回答表中最近回答的id
            questionService.lambdaUpdate()
                    .set(InteractionQuestion::getLatestAnswerId,po.getId())
                    .setSql(true,"answer_times = answer_times + 1")
                    .set(InteractionQuestion::getStatus,1)
                    .eq(InteractionQuestion::getId,questionId)
                    .update();
        }else{
            //2.2非回答：回答下评论数+1
            if (answerId != null){
                this.lambdaUpdate()
                        .setSql("reply_times = reply_times + 1")
                        .eq(InteractionReply::getId,answerId)
                        .update();
            }

        }
        //3.是否是学生提交
        if (dto.getIsStudent()!= null && dto.getIsStudent()) {
            //3.2是问题表状态未查看
            questionService.lambdaUpdate()
                    .eq(InteractionQuestion::getId,questionId)
                    .set(InteractionQuestion::getStatus,0)
                    .update();
        }
    }
}
